package com.wmh.baseservice.operationaid.service.impl;

import cn.hutool.core.util.BooleanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.structure.LambdaQueryWrapperX;
import com.wmh.baseservice.common.utils.web.UserUtil;
import com.wmh.baseservice.operationaid.entity.KeyWordUsageRecord;
import com.wmh.baseservice.operationaid.enums.KeyWordUsageEnums;
import com.wmh.baseservice.operationaid.mapper.KeyWordUsageRecordMapper;
import com.wmh.baseservice.operationaid.pojo.vo.keyWordUsageRecord.KeyWordUsageRecordCommitReqVO;
import com.wmh.baseservice.operationaid.pojo.vo.keyWordUsageRecord.KeyWordUsageRecordMaskReqVO;
import com.wmh.baseservice.operationaid.pojo.vo.keyWordUsageRecord.KeyWordUsageRecordRespVO;
import com.wmh.baseservice.operationaid.service.KeyWordUsageRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.wmh.baseservice.operationaid.enums.KeyWordUsageEnums.*;

/**
 * @author dongaolong
 * @description 针对表【operation_aid_key_word_usage_record】的数据库操作Service实现
 * @createDate 2023-06-20 15:27:56
 */
@Service
public class KeyWordUsageRecordServiceImpl extends ServiceImpl<KeyWordUsageRecordMapper, KeyWordUsageRecord>
        implements KeyWordUsageRecordService {

    @Resource
    private KeyWordUsageRecordMapper keyWordUsageRecordMapper;

    @Resource
    private UserUtil userUtil;

    @Override
    public void commitUsageRecord(KeyWordUsageRecordCommitReqVO reqVO) {
        Long userId = userUtil.getId();
        // 获取未分组的记录
        KeyWordUsageRecord keyWordUsageRecord = getKeyWordUsageRecordNoGroup(reqVO.getName(),reqVO.getCategoryName(), userId);
        if (keyWordUsageRecord == null) {
            keyWordUsageRecord = new KeyWordUsageRecord();
        }
        BeanUtils.copyProperties(reqVO,keyWordUsageRecord);
        keyWordUsageRecord.setAdId(userId);
        keyWordUsageRecord
                .setIsAppendZtc(BooleanUtil.isTrue(reqVO.getIsAppendZtc()) ? 1 : 0)
                .setIsGenerateTitle(BooleanUtil.isTrue(reqVO.getIsGenerateTitle()) ? 1 : 0)
                .setIsGenerateOrderPlan(BooleanUtil.isTrue(reqVO.getIsGenerateOrderPlan()) ? 1 : 0);
        saveOrUpdate(keyWordUsageRecord);
    }

    @Override
    public void updateGroupId(List<Long> ids, Long groupId) {
        boolean r = update(new UpdateWrapper<KeyWordUsageRecord>().lambda()
                .in(KeyWordUsageRecord::getId, ids)
                .eq(KeyWordUsageRecord::getAdId,userUtil.getId())
                .set(KeyWordUsageRecord::getGroupId, groupId == 0L ? null : groupId));
        if (!r){
            throw new ServiceException("更新失败");
        }
    }

    @Override
    public List<KeyWordUsageRecord> getListNoGroup(String categoryName, Long adId) {
        return baseMapper.selectListNoGroup(categoryName, adId);
    }

    @Override
    public List<KeyWordUsageRecord> getList(String categoryName, Long adId, Long groupId) {
        return baseMapper.selectList(categoryName,adId,groupId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markUsageRecord(KeyWordUsageRecordMaskReqVO reqVO) {
        if (!BooleanUtil.or(reqVO.getIsAppendZtc(), reqVO.getIsGenerateOrderPlan(), reqVO.getIsGenerateTitle())) {
            throw new ServiceException("请至少选择一种用途操作");
        }
        Long adId = userUtil.getId();
        List<KeyWordUsageRecordMaskReqVO.KeyWord> keyWordList = JSON.parseArray(reqVO.getKeyWordJsonList(), KeyWordUsageRecordMaskReqVO.KeyWord.class);

        List<KeyWordUsageRecord> recordList;
        if (reqVO.getGroupId() == null){
            // 获取当前用户已经存在且未分组的记录
            recordList = getListNoGroup(reqVO.getCategoryName(), adId);
        }else{
            // 获取当前用户已存在且已分组的记录
            recordList = getList(reqVO.getCategoryName(), adId,reqVO.getGroupId());
        }
        // 将当前存在的记录直接以关键词名称为 key 转为 map 结构
        Map<String, KeyWordUsageRecord> map = recordList.stream().collect(Collectors.toMap(KeyWordUsageRecord::getName, i -> i));
        // 按要标记的名称构建 保存的列表
        List<KeyWordUsageRecord> saveList = keyWordList.stream().map(item -> {
            KeyWordUsageRecord v;
            if (map.containsKey(item.getName())) {
                v = map.get(item.getName());
            } else {
                v = new KeyWordUsageRecord()
                        .setAdId(adId)
                        .setCategoryName(reqVO.getCategoryName())
                        .setName(item.getName())
                        .setIsAppendZtc(0)
                        .setIsGenerateOrderPlan(0)
                        .setIsGenerateTitle(0)
                        .setGroupId(reqVO.getGroupId());
            }
            // 设置指数相关字字段(即,若记录已存在则数据相关字段会被更新)
            BeanUtils.copyProperties(item, v);
            return v;

        }).collect(Collectors.toList());
        // 根据请求参数确定标记打开还是关闭
        saveList.forEach(i -> {
            Integer v = BooleanUtil.isTrue(reqVO.getMarkSwitch()) ? 1 : 0;
            if (BooleanUtil.isTrue(reqVO.getIsAppendZtc())) {
                i.setIsAppendZtc(v);
            }
            if (BooleanUtil.isTrue(reqVO.getIsGenerateTitle())) {
                i.setIsGenerateTitle(v);
            }
            if (BooleanUtil.isTrue(reqVO.getIsGenerateOrderPlan())) {
                i.setIsGenerateOrderPlan(v);
            }
        });
        if (!saveOrUpdateBatch(saveList)) {
            throw new ServiceException("操作失败,重试或练习管理员");
        }
    }

    @Override
    public List<KeyWordUsageRecordRespVO> getQueryKeyWordUsageRecord(Long adId, String categoryName, KeyWordUsageEnums type,Long groupId) {
        LambdaQueryWrapperX<KeyWordUsageRecord> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eq(KeyWordUsageRecord::getAdId, adId)
                .eq(KeyWordUsageRecord::getCategoryName, categoryName)
                //约束指定分组
                .eq(!Objects.isNull(groupId) && !Objects.equals(0L,groupId),KeyWordUsageRecord::getGroupId,groupId)
                //约束未分组
                .isNull(Objects.equals(0L,groupId),KeyWordUsageRecord::getGroupId)
                .orderByDesc(KeyWordUsageRecord::getCreateTime);
        switch (type) {
            case IS_APPEND_ZTC:
                queryWrapper.eq(KeyWordUsageRecord::getIsAppendZtc, 1);
                break;
            case IS_GENERATE_TITLE:
                queryWrapper.eq(KeyWordUsageRecord::getIsGenerateTitle, 1);
                break;
            case IS_GENERATE_ORDER_PLAN:
                queryWrapper.eq(KeyWordUsageRecord::getIsGenerateOrderPlan, 1);
                break;
            default:
                throw new IllegalArgumentException("不支持的关键词使用类型: " + type);
        }
        return keyWordUsageRecordMapper.selectList(queryWrapper)
                .stream()
                .map(KeyWordUsageRecordRespVO::build).collect(Collectors.toList());
    }

    @Override
    public void getStatusKeyWordUsageRecord(List<String> ids, KeyWordUsageEnums type) {
        baseMapper.update(null,new UpdateWrapper<KeyWordUsageRecord>()
                .lambda()
                .in(KeyWordUsageRecord::getId,ids)
                .set(Objects.equals(type,IS_APPEND_ZTC),KeyWordUsageRecord::getIsAppendZtc,0)
                .set(Objects.equals(type,IS_GENERATE_TITLE),KeyWordUsageRecord::getIsGenerateTitle,0)
                .set(Objects.equals(type,IS_GENERATE_ORDER_PLAN),KeyWordUsageRecord::getIsGenerateOrderPlan,0)
        );
    }

    /**
     * 根据name、categoryName、adId获未分组的记录
     */
    private KeyWordUsageRecord getKeyWordUsageRecordNoGroup(String name, String categoryName, Long adId) {
        LambdaQueryWrapper<KeyWordUsageRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(KeyWordUsageRecord::getName, name)
                .eq(KeyWordUsageRecord::getCategoryName, categoryName)
                .eq(KeyWordUsageRecord::getAdId, String.valueOf(adId))
                .isNull(KeyWordUsageRecord::getGroupId);
        return keyWordUsageRecordMapper.selectOne(queryWrapper);
    }
}
